 1.Spark原理之SparkContext中SparkContext内部组件
   
   Spark应用程序的第一步就是创建并初始化SparkContext，SparkContext的初始化过程包含了内部组件的创建和准
备，主要涉及网络通信、分布式、消息、存储、计算、调度、缓存、度量、清理、文件服务和UI等方面。
   SparkContext 是 Spark 程序主要功能的入口点，链接Spark集群，创建RDD、累加器和广播变量，一个线程只能运
行一个SparkContext。
   SparkContext在应用程序中将外部数据转换成RDD，建立了第一个RDD，也就是说SparkContext建立了RDD血缘关
系的根，是DAG的根源。
  private var _conf: SparkConf = _
  private var _eventLogDir: Option[URI] = None
  private var _eventLogCodec: Option[String] = None
  private var _listenerBus: LiveListenerBus = _
  private var _env: SparkEnv = _
  private var _statusTracker: SparkStatusTracker = _
  private var _progressBar: Option[ConsoleProgressBar] = None
  private var _ui: Option[SparkUI] = None
  private var _hadoopConfiguration: Configuration = _
  private var _executorMemory: Int = _
  private var _schedulerBackend: SchedulerBackend = _
  private var _taskScheduler: TaskScheduler = _
  private var _heartbeatReceiver: RpcEndpointRef = _
  @volatile private var _dagScheduler: DAGScheduler = _
  private var _applicationId: String = _
  private var _applicationAttemptId: Option[String] = None
  private var _eventLogger: Option[EventLoggingListener] = None
  private var _executorAllocationManager: Option[ExecutorAllocationManager] = None
  private var _cleaner: Option[ContextCleaner] = None
  private var _listenerBusStarted: Boolean = false
  private var _jars: Seq[String] = _
  private var _files: Seq[String] = _
  private var _shutdownHookRef: AnyRef = _
  private var _statusStore: AppStatusStore = _
   SparkContext 内部组件：
       SparkConf。Spark Application 的配置，用来设置 Spark 的 KV 格式的参数。可用通过 new 实例化一个
SparkConf 的对象，这可以把所有的以 spark 开头的属性配置好，使用 SparkConf 进行参数设置的优先级是高
于属性文件，通过 new SparkConf(false) 可以在进行单元测试的时候不去读取外部的设置。所有的 setter
方法都支持链式表达。一旦SparkConf对象传给Spark，会被其他组件clone，并且不能再动态的被任何用户修改
       SparkEnv： SparkEnv 是Spark的执行环境对象，其中包括与众多Executor执行相关的对象。Executor 有自己
的Spark的执行环境SparkEnv。有了SparkEnv，就可以将数据存储在存储体系中；就能利用计算引擎对计算任务进行
处理，就可以在节点间进行通信等。在local模式下Driver会创建Executor,local-cluster部署模式或者Standalone
部署模式下Worker的CoarseGrainedExecutorBackend 进程中也会创建Executor，所以SparkEnv存在于Driver或者
CoarseGrainedExecutorBackend进程中。SparkEnv包含了很多重要的组件，完成不同的功能
       DAGScheduler。DAG调度器，调度系统中最重要的组件之一，负责创建job，将DAG的RDD划分为不同的stage,
提交stage
       TaskScheduler。任务调度器，调度系统中最重要的组件之一，按照调度算法对集群管理器已经分配给应用程
序的资源进行二次调度后分配任务，TaskScheduler调度的Task是DAGScheduler创建的，因此DAGScheduler是
TaskScheduler的前置调度器
       SchedulerBackend。用于对接不同的资源管理系统
       LiveListenerBus：事件总线。接收各个使用方的事件，以异步的方式对事件进行匹配和处理
       SparkUI：用户界面，依赖计算引擎、调度系统、存储体系、作业、阶段、存储、执行器等组件的监控数据，以
SparkListenerEnvent的形式投递给Live Listener，Spark从SparkListener中读取数据
       SparkStatusTracker：状态跟踪器，提供对作业、stage等的监控信息
       _shutdownHookRef：任务退出时执行清理任务
       ConsoleProgressBar：进度条，利用SparkStatusTracker的API，在控制台展示Stage的进度
	   ContextCleaner：上下文清理器，用异步方式清理超出应用程序范围的RDD、ShuffleDependency和BroadCast
	   EventLoggingListener：将事件日志的监听器，Spark可选组件，spark.eventLog.enabled=true时启动
	   ExecutorAllocationManager： Executor动态分配管理器，根据工作负载动态调整Executor的数量，在
spark.dynamicAllocation.enabled=true的前提下,和非local模式下或者spark.dynamicAllocation.testing=true时启动
       hadoopConfiguration()： hadoop的配置信息，如果使用的是系统SPARK_YARN_MODE=true或者环境变量
SPARK_YARN_MODE=true时，启用yarn配置，否则启用hadoop配置
       heartbeatReceiver(RpcEndpointRef)：心跳接收器，Executor都会向heartbeatReceiver发送心跳信息，
heartbeatReceiver接收到信息后，更新executor最后的可见时间，然后传递给taskScheduler做进一步处理

 2.SparkEnv内部组件
   
   SparkEnv是spark计算层的基石，不管是 Driver 还是 Executor，都需要依赖SparkEnv来进行计算，它是Spark的执
行环境对象，其中包括与众多Executor执行相关的对象。Spark对任务的计算都依托于Executor的能力，所有的Executor 
都有自己的 Spark 的执行环境 SparkEnv。
   有了 SparkEnv，可以将数据存储在存储体系中；利用计算引擎对计算任务进行处理，可以在节点间进行通信等。
 class SparkEnv (
    val executorId: String,
    private[spark] val rpcEnv: RpcEnv,
    val serializer: Serializer,
    val closureSerializer: Serializer,
    val serializerManager: SerializerManager,
    val mapOutputTracker: MapOutputTracker,
    val shuffleManager: ShuffleManager,
    val broadcastManager: BroadcastManager,
    val blockManager: BlockManager,
    val securityManager: SecurityManager,
    val metricsSystem: MetricsSystem,
    val memoryManager: MemoryManager,
    val outputCommitCoordinator: OutputCommitCoordinator,
    val conf: SparkConf) extends Logging {
       ExecutorId。每一个Executor在向Driver端注册时，都会生成一个ExecutorId，对Driver来说，这个ExecutorId
就是Executor的唯一标识，它会一直伴随Executor；
       RpcEnv。通过Netty技术来实现对组件之间的通信；
       Serializer。Spark使用的序列化器，默认使用Java的序列化器org.apache.spark.serializer.JavaSerializer；
	   SerializerManager。Spark 中很多对象在通用网络传输或者写入存储体系时，都需要序列化。SparkEnv 中有
两个序列化组件，分别是SerializerManager和ClosureSerializer。serializer默认为Java的序列化器
org.apache.spark.serializer.JavaSerializer，用户可以通过spark.serializer属性配置其他的序列化实现，如
org.apache.spark.serializer.KryoSerializer。而 closureSerializer 的实际类型固定为
org.apache.spark.serializer.JavaSerializer，用户不能够自己指定。JavaSerializer采用 Java 语言自带的序列化
API 实现；
       MapOutPutTracker。MapOutputTracker 用于跟踪Map阶段任务的输出状态，此状态便于Reduce阶段任务获取
地址及中间结果。每个Map任务或者Reduce任务都会有其唯一标识，分别为mapId和reduceId。每个Reduce任务的输入
可能是多个Map任务的输出，Reduce会到各个Map任务的所在节点上拉取Block。每个Shuffle过程都有唯一的表示
shuffleId。MapOutputTracker 有两个子类：MapOutputTrackerMaster(for driver)和MapOutputTrackerWorker 
(for executors)；因为它们使用了不同的HashMap来存储元数据；
       ShuffleManager。ShuffleManager负责管理本地及远程的Block数据的shuffle操作。ShuffleManager根据默
认的 spark.shuffle.manager 属性，通过反射方式生成的SortShuffleManager的实例。默认使用的是sort模式
的SortShuffleManager；
       BroadcastManager。BroadcastManager用于将配置信息和序列化后的RDD、Job以及ShuffleDependency等
信息在本地存储。如果为了容灾，也会复制到其他节点上；
       BlockManager。BlockManager负责对Block的管理；
       SecurityManager。主要对帐号、权限以及身份认证进行设置和管理；
	   MetricsSystem。Spark内置的测量系统。度量系统根据当前实例是 Driver还是Executor 有所区别：
	        当前实例为Driver：创建度量系统,并且指定度量系统的实例名为driver，然后等待SparkContext中的
任务调度器 TaskScheculer 告诉度量系统后再启动；
            当前实例为 Executor：设置spark.executor.id属性为当前Executor的ID,然后再创建并启动度量系统；
	   MemoryManager。MemoryManager的主要实现有StaticMemoryManager和UnifiedMemoryManager(默认)。
       OutputCommitCoordinator。当Spark应用程序使用了Spark SQL(包括 Hive)或者需要将任务的输出保存到HDFS
时,就会用到输出提交协调器 OutputCommitCoordinator，OutputCommitCoordinator将决定任务是否可以提交输出到
HDFS。无论是Driver还是Executor,在SparkEnv中都包含了子组件OutputCommitCoordinator。在Driver上注册了
OutputCommitCoordinatorEndpoint，在所有Executor上的OutputCommitCoordinator都是通过  
OutputCommitCoordinatorEndpoint的 RpcEndpointRef来询问Driver上的OutputCommitCoordinator,
是否能够将输出提交到HDFS。	   